package Wallpaper::Daemon;
$VERSION = sprintf "%.3f", 1 + substr(q$Revision: 159 $,9)/1000;

use Wallpaper::Configuration;
use POSIX qw( setsid );
use strict;

my $general_config = Wallpaper::Configuration->general;
my $debug          = $general_config->{ 'debug' };

print "Daemonizing ... \n";

# The current working directory should be changed with chdir to the root
# directory (/). This is necessary to avoid using a working directory that
# resides on a mounted partition. If the process is started on a mounted
# partition, the system administrator wouldn't be able to unmount the partition
# until the process was halted.

chdir '/' or die "Can't chdir to /: $!";

# The umask determines the default permissions new files are assigned. Setting
# umask to 0 removes the defaults that might otherwise disable permissions the
# daemon intended to enable when creating files.

umask 0;

# Redirect input to null, and direct standard output and errors to a logfile
# if debug is set.

open STDIN,  '/dev/null'      or die "Can't read /dev/null: $!";
if ( $debug ) {
    open STDOUT, ">$ENV{'HOME'}/.wall.log" or die "Can't write to $ENV{'HOME'}/.wall.log: $!";
    open STDERR, ">$ENV{'HOME'}/.wall.log" or die "Can't write to $ENV{'HOME'}/.wall.log: $!";
} else {
    open STDOUT, ">/dev/null" or die "Can't write to /dev/null: $!";
    open STDERR, ">/dev/null" or die "Can't write to /dev/null: $!";
}
# The first thing a daemon should do is fork() a child process and have the
# parent process exit(). This is necessary for several reasons. First, it
# disassociates the process from the controlling terminal, or the login shell.
# Second, it removes the process from the process group that initiated the
# program. This ensures that the process is not a process group leader, which is
# required for setsid() to run successfully.

defined( my $pid = fork ) or die "Can't fork: $!";

open( PIDFILE, "> $ENV{'HOME'}/.wall.pid" );
print PIDFILE $pid;
close PIDFILE;

exit if $pid;

# setsid() is a POSIX function that turns the process into a session leader,
# group leader, and ensures that it doesn't have a controlling terminal.

setsid or die "Can't start a new session: $!";

1;
